/*
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import 'dart:math';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class PicBean {
  String name;
  int id;
  int index = 0;
  PicBean(this.name, this.id);

  setIndex(int index) {
    this.index = index;
    return this;
  }

  @override
  String toString() {
    return "PicBean(name=$name, id=$id, index=$index)";
  }
}

class PicturePage extends StatefulWidget {
  const PicturePage({super.key});
  @override
  State<PicturePage> createState() => _PicturePageState();
}

class _PicturePageState extends State<PicturePage> {
  List<PicBean> pics = [
    PicBean("assets/images/1.png", 0),
    PicBean("assets/images/2.jpeg", 0),
    PicBean("assets/images/3.jpeg", 0),
    PicBean("assets/images/4.jpg", 0),
    PicBean("assets/images/6.jpg", 0),
    PicBean("assets/images/1.png", 0),
    PicBean("assets/images/2.jpeg", 0),
    PicBean("assets/images/3.jpeg", 0),
    PicBean("assets/images/4.jpg", 0),
    PicBean("assets/images/6.jpg", 0),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("daex_texture"),
      ),
      body: ListView.builder(
        itemCount: pics.length + 1,
        itemBuilder: (context, index) {
          if (index == pics.length) {
            return _buildBottom(context);
          }
          PicBean picBean = pics[index];
          return Column(
            children: [
              PictureWidget(bean: picBean),
              ElevatedButton(
                onPressed: () {
                  picBean.name = pics[Random().nextInt(10) % pics.length].name;
                  setTexture(picBean.id, picBean.name);
                },
                child: const Text("更换图片"),
              ),
            ],
          );
        },
      ),
    );
  }

  @override
  void initState() {
    debugPrint("_PicturePageState initState");
    super.initState();
  }

  @override
  void dispose() {
    debugPrint("_PicturePageState dispose");
    super.dispose();
  }
}

_buildBottom(BuildContext context) {
  return Center(
    child: ElevatedButton(
      onPressed: () {
        _gotoNextPage(context);
      },
      child: const Text("跳转"),
    ),
  );
}

_gotoNextPage(BuildContext context) {
  Navigator.push(context, MaterialPageRoute(
    builder: (BuildContext context) {
      return const PicturePage();
    },
  ));
}

class PictureWidget extends StatefulWidget {
  const PictureWidget({super.key, required this.bean});
  final PicBean bean;

  @override
  State<PictureWidget> createState() => _PictureWidgetState(bean);
}

class _PictureWidgetState extends State<PictureWidget> {
  final PicBean bean;
  bool isDisposed = false;

  _PictureWidgetState(this.bean);

  @override
  void initState() {
    super.initState();
    if (isOhos()) {
      registerTexture(bean.name).then((value) {
        bean.id = value;
        if (isDisposed) {
          // 已执行了 dispose 方法
          // dispose 执行后再调用 setState 会报错
          // 此时需要执行 unregisterTexture ，避免内存泄露
          unregisterTexture(value);
        } else {
          setState(() {});
        }
      }).catchError((e) {
        debugPrint("registerTexture error: $e");
      });
    }
  }

  @override
  void dispose() {
    if (isOhos()) {
      isDisposed = true;
      unregisterTexture(bean.id).then((value) => {}).catchError((e) {
        debugPrint("unregisterTexture error: $e");
      });
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (isOhos()) {
      return bean.id > 0
          ? getTextureBody(context, bean)
          : const Text('loading...');
    } else {
      return Image.asset(bean.name);
    }
  }

  Widget getTextureBody(BuildContext context, PicBean picBean) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        SizedBox(
          width: 300,
          height: 300,
          child: Texture(textureId: picBean.id),
        ),
        Container(
          height: 10,
        ),
      ],
    );
  }
}

bool isOhos() {
  return defaultTargetPlatform == TargetPlatform.ohos;
}

const MethodChannel _channel = MethodChannel('PictureChannel');

registerTexture(String picName) async {
  int id = await _channel.invokeMethod("registerTexture", {'pic': picName});
  return id;
}

unregisterTexture(int textureId) async {
  await _channel.invokeMethod('unregisterTexture', {'textureId': textureId});
}

setTexture(int textureId, String picName) async {
  await _channel.invokeMethod("setPixelMap", [textureId, picName]);
}